<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Making RTP Pages</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Making RTP Pages' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inbuildn.html">Inbuild Modules</a></li><li><a href="index.html">supervisor</a></li><li><a href="index.html#7">Chapter 7: Extension Management</a></li><li><b>Making RTP Pages</b></li></ul></div>
<p class="purpose">To turn Markdown source into outcome or run-time-problem pages.</p>

<ul class="toc"><li><a href="7-mrp.html#SP1">&#167;1. Introduction</a></li><li><a href="7-mrp.html#SP2">&#167;2. RTP-flavoured Markdown</a></li><li><a href="7-mrp.html#SP3">&#167;3. Models</a></li><li><a href="7-mrp.html#SP4">&#167;4. Making one page</a></li><li><a href="7-mrp.html#SP5">&#167;5. Making a batch of pages</a></li><li><a href="7-mrp.html#SP6">&#167;6. Making a batch from a roster</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction.</b>This section is descended from an earlier command-line tool, <span class="extract"><span class="extract-syntax">inrtps</span></span>, which
was removed in August 2023. Its purpose was to generate simple HTML pages
which could be displayed inside the Inform GUI apps to explain run-time problems
or other issues to the user. But it was very inflexible, making it difficult to
provide RTPs from kits other than the built-in ones, and it used a notation of
its own. The code below, which is activated from <span class="extract"><span class="extract-syntax">inbuild</span></span> using the <span class="extract"><span class="extract-syntax">-markdown-*</span></span>
command-line switches, uses Markdown instead and is quite flexible in the
services it provides.
</p>

<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. RTP-flavoured Markdown.</b>We do not want examples embedded in RTPs, and we do not want level-1 headings
to be interpreted as chapter headings, since we need those for problem titles.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="function-syntax">RTPPages::RTP_flavoured_Markdown</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">RTPPages::RTP_flavoured_Markdown</span></span>:<br/><a href="7-mrp.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MarkdownVariations::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"RTP-flavoured Markdown"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">MarkdownVariations::copy_features_of</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">InformFlavouredMarkdown::variation</span><span class="plain-syntax">());</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">MarkdownVariations::remove_feature</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DESCRIPTIVE_INFORM_HEADINGS_MARKDOWNFEATURE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">MarkdownVariations::remove_feature</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">EMBEDDED_EXAMPLES_MARKDOWNFEATURE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">RTP_flavoured_Markdown</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Models.</b>Markdown is in practice not enough to make a stand-alone HTML file, since it
renders only to content suitable for the body, and cannot render the head,
any CSS needed, and so on. We therefore generate pages from "models", which
are HTML pages where the place where the content should go is marked as a
placeholder <span class="extract"><span class="extract-syntax">[CONTENT]</span></span>, and so on.
</p>

<p class="commentary">In the standard Inform distribution, the internal resources nest contains a
subdirectory called <span class="extract"><span class="extract-syntax">HTML</span></span>, and that's where we look for models by default.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="function-syntax">RTPPages::internal_HTML_path</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">RTPPages::internal_HTML_path</span></span>:<br/><a href="7-mrp.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">M</span><span class="plain-syntax"> = </span><a href="1-ic.html#SP16" class="function-link"><span class="function-syntax">Supervisor::internal</span></a><span class="plain-syntax">()-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">M</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"HTML"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="function-syntax">RTPPages::default_model</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">RTPPages::default_model</span></span>:<br/><a href="7-mrp.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><a href="7-mrp.html#SP3" class="function-link"><span class="function-syntax">RTPPages::internal_HTML_path</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">I</span><span class="string-syntax">"rtp-model.html"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Making one page.</b>So, then, <span class="extract"><span class="extract-syntax">RTPPages::make_one(M, F, T, V)</span></span> generates an HTML page from model
<span class="extract"><span class="extract-syntax">M</span></span> using Markdown source in <span class="extract"><span class="extract-syntax">F</span></span>, writing to file <span class="extract"><span class="extract-syntax">T</span></span> and using the dialect
of Markdown indicated by <span class="extract"><span class="extract-syntax">V</span></span>.
</p>

<p class="commentary">Only <span class="extract"><span class="extract-syntax">F</span></span> is mandatory. <span class="extract"><span class="extract-syntax">M</span></span> defaults to the RTP template; <span class="extract"><span class="extract-syntax">T</span></span> defaults to writing
the HTML to the same directory as the source, but with <span class="extract"><span class="extract-syntax">.html</span></span> not <span class="extract"><span class="extract-syntax">.md</span></span> as
the file extension; <span class="extract"><span class="extract-syntax">V</span></span> defaults to RTP-flavoured Markdown.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">RTP_maker_state</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">markdown_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">content</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variation</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pcode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">output_stream</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">RTP_maker_state</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RTPPages::make_one</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">RTPPages::make_one</span></span>:<br/><a href="7-mrp.html#SP5">&#167;5</a>, <a href="7-mrp.html#SP7_1">&#167;7.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">model</span><span class="plain-syntax">, </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">model</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">model</span><span class="plain-syntax"> = </span><a href="7-mrp.html#SP3" class="function-link"><span class="function-syntax">RTPPages::default_model</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">variation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">variation</span><span class="plain-syntax"> = </span><a href="7-mrp.html#SP2" class="function-link"><span class="function-syntax">RTPPages::RTP_flavoured_Markdown</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::set_extension</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"html"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"required to have a source filename"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">content</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TextFiles::write_file_contents</span><span class="plain-syntax">(</span><span class="identifier-syntax">content</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Errors::fatal_with_file</span><span class="plain-syntax">(</span><span class="string-syntax">"no Markdown source"</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">content</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Streams::open_to_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">UTF8_ENC</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Errors::fatal_with_file</span><span class="plain-syntax">(</span><span class="string-syntax">"unable to write RTP page file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">RTP_maker_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Markdown::parse_extended</span><span class="plain-syntax">(</span><span class="identifier-syntax">content</span><span class="plain-syntax">, </span><span class="identifier-syntax">variation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">variation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">variation</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">pcode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">(); </span><span class="identifier-syntax">Filenames::write_unextended_leafname</span><span class="plain-syntax">(</span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">pcode</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">output_stream</span><span class="plain-syntax"> = </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax"> == </span><span class="identifier-syntax">HEADING_MIT</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Markdown::get_heading_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">title</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">stashed</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Filenames::get_leafname</span><span class="plain-syntax">(</span><span class="identifier-syntax">model</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="string-syntax">"none"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Markdown::render_extended</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">content</span><span class="plain-syntax">, </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">variation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">model</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to read file of model HTML"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            &amp;</span><a href="7-mrp.html#SP4" class="function-link"><span class="function-syntax">RTPPages::make_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">state</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">Streams::close</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">content</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RTPPages::make_helper</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">RTP_maker_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ts</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">RTP_maker_state</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ts</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">output_stream</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-mrp.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Expand the escapes</span><span class="named-paragraph-number">4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure RTP_maker_state is accessed in 2/wrk, 2/edt, 2/cps, 2/rqr, 2/jm, 3/bg, 3/is, 4/ebm, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/inc, 7/tm, 7/eip, 7/ti, 7/tc, 7/dc, 7/dr, 7/im and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>&#167;4.1. </b>Inside the model, we recognise certain square-bracketed words as placeholders
which we expand into appropriate material:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand the escapes</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">source</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">source</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">source</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"(%c*?)%[(%C+)%](%c*)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">insertion</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="7-mrp.html#SP4_1_1" class="named-paragraph-link"><span class="named-paragraph">Insert the insertion</span><span class="named-paragraph-number">4.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">source</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">source</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[2]);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">source</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">source</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Regexp::dispose_of</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-mrp.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_1" class="paragraph-anchor"></a><b>&#167;4.1.1. </b>The precursor tool <span class="extract"><span class="extract-syntax">inrtps</span></span> used the awkward notations <span class="extract"><span class="extract-syntax">*1</span></span> to <span class="extract"><span class="extract-syntax">*5</span></span> for
placeholders. <span class="extract"><span class="extract-syntax">[RTPCODE]</span></span> is the new <span class="extract"><span class="extract-syntax">*1</span></span>; <span class="extract"><span class="extract-syntax">[CONTENT]</span></span> is the new <span class="extract"><span class="extract-syntax">*2</span></span>;
<span class="extract"><span class="extract-syntax">[TITLE]</span></span> is the new <span class="extract"><span class="extract-syntax">*3</span></span>; <span class="extract"><span class="extract-syntax">INFORMCSS</span></span> is the new <span class="extract"><span class="extract-syntax">*5</span></span>, and <span class="extract"><span class="extract-syntax">*4</span></span> has been
abolished.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert the insertion</span><span class="named-paragraph-number">4.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"INFORMCSS"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TextFiles::write_file_contents</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">InstalledFiles::filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSS_SET_BY_PLATFORM_IRES</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TextFiles::write_file_contents</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">InstalledFiles::filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSS_FOR_STANDARD_PAGES_IRES</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"RTPCODE"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ts</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pcode</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"CONTENT"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Markdown::render_extended</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">ts</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">content</span><span class="plain-syntax">, </span><span class="identifier-syntax">ts</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"TITLE"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ts</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"[%S]"</span><span class="plain-syntax">, </span><span class="identifier-syntax">insertion</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-mrp.html#SP4_1">&#167;4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Making a batch of pages.</b>This works through all Markdown files in a source folder and converts them
into the destination, using a common model. Again, only <span class="extract"><span class="extract-syntax">from_folder</span></span> is
mandatory.
</p>

<p class="commentary">If a file <span class="extract"><span class="extract-syntax">roster.txt</span></span> exists in the source folder, we follow that: see below.
If not, we convert every file whose leafname has the extension <span class="extract"><span class="extract-syntax">.md</span></span> or <span class="extract"><span class="extract-syntax">.MD</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RTPPages::work_through_directory</span><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">model</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no directory given to read from"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to_folder</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">to_folder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">roster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"roster.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TextFiles::exists</span><span class="plain-syntax">(</span><span class="identifier-syntax">roster</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><a href="7-mrp.html#SP6" class="function-link"><span class="function-syntax">RTPPages::work_through_roster</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">variation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">counter</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to_folder</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">to_folder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Directories::listing</span><span class="plain-syntax">(</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">entry</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Platform::is_folder_separator</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_last_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::ends_with</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">".md"</span><span class="plain-syntax">)) || (</span><span class="identifier-syntax">Str::ends_with</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">".MD"</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">to_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::set_extension</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"html"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><a href="7-mrp.html#SP4" class="function-link"><span class="function-syntax">RTPPages::make_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">model</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">variation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">counter</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"%d stand-alone page(s) written (%p -&gt; %p)\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">counter</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_folder</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Making a batch from a roster.</b>This is called by the above, but can also be called directly. Once again,
only <span class="extract"><span class="extract-syntax">from_folder</span></span> is mandatory.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">RTP_roster_state</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">source_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">destination_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">models_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variation</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">counter</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">RTP_roster_state</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RTPPages::work_through_roster</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">RTPPages::work_through_roster</span></span>:<br/><a href="7-mrp.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">models_folder</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">markdown_variation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no directory given to read from"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">models_folder</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">models_folder</span><span class="plain-syntax"> = </span><a href="7-mrp.html#SP3" class="function-link"><span class="function-syntax">RTPPages::internal_HTML_path</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to_folder</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">to_folder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">roster</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">roster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"roster.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">RTP_roster_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">source_folder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">destination_folder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">models_folder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">models_folder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">variation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">variation</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">counter</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to read roster file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        &amp;</span><a href="7-mrp.html#SP7" class="function-link"><span class="function-syntax">RTPPages::roster_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">state</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"%d stand-alone page(s) written (following %f)\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">state</span><span class="plain-syntax">.</span><span class="element-syntax">counter</span><span class="plain-syntax">, </span><span class="identifier-syntax">roster</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure RTP_roster_state is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>Thus, the following is called on each line in turn of the roster file. In
a roster file, leading and trailing white space is removed. Blank lines are
ignored, and lines beginning with <span class="extract"><span class="extract-syntax">!</span></span> are ignored as comments. All other
lines are commands to make one HTML page.
</p>

<p class="commentary">The line <span class="extract"><span class="extract-syntax">&gt; TOKEN</span></span> means "convert <span class="extract"><span class="extract-syntax">TOKEN.md</span></span> in the source folder into
<span class="extract"><span class="extract-syntax">TOKEN.html</span></span> in the destination folder, using the default model". <span class="extract"><span class="extract-syntax">TOKEN</span></span>
must not contain spaces.
</p>

<p class="commentary">The line <span class="extract"><span class="extract-syntax">&gt; MODEL: TOKEN</span></span> means "convert <span class="extract"><span class="extract-syntax">TOKEN.md</span></span> in the source folder into
<span class="extract"><span class="extract-syntax">TOKEN.html</span></span> in the destination folder, using <span class="extract"><span class="extract-syntax">MODEL</span></span> as model". <span class="extract"><span class="extract-syntax">MODEL</span></span>
should be a leafname in the models directory.
</p>

<p class="commentary">Finally, <span class="extract"><span class="extract-syntax">&gt; MODEL: FROM --&gt; TO</span></span> means the same, except that the Markdown
is read from <span class="extract"><span class="extract-syntax">FROM.md</span></span> and written to <span class="extract"><span class="extract-syntax">TO.html</span></span>. <span class="extract"><span class="extract-syntax">FROM</span></span> and <span class="extract"><span class="extract-syntax">TO</span></span> must not
contain spaces.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RTPPages::roster_helper</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">RTPPages::roster_helper</span></span>:<br/><a href="7-mrp.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">RTP_roster_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">roster_state</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">RTP_roster_state</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_first_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">) == </span><span class="character-syntax">'!'</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">equivalent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">model</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt; *(%c*?) *: *(%C+) *--&gt; *(%C+)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">model</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]; </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[2]; </span><span class="identifier-syntax">equivalent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="7-mrp.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Act on roster item</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt; *(%c+?) *: *(%C+)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">model</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]; </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1]; </span><span class="identifier-syntax">equivalent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="7-mrp.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Act on roster item</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&gt; *(%C+)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">model</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]; </span><span class="identifier-syntax">equivalent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="7-mrp.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Act on roster item</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">, </span><span class="string-syntax">"Line not recognised in page roster file: '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Errors::in_text_file_S</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Regexp::dispose_of</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>&#167;7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on roster item</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">, </span><span class="string-syntax">"%S.html"</span><span class="plain-syntax">, </span><span class="identifier-syntax">token</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">roster_state</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">destination_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">leaf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">)</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">md_leaf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">md_leaf</span><span class="plain-syntax">, </span><span class="string-syntax">"%S.md"</span><span class="plain-syntax">, </span><span class="identifier-syntax">equivalent</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">MD</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">roster_state</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">source_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">md_leaf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">md_leaf</span><span class="plain-syntax">)</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">model_to_follow</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">roster_state</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">models_folder</span><span class="plain-syntax">, </span><span class="identifier-syntax">model</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="7-mrp.html#SP4" class="function-link"><span class="function-syntax">RTPPages::make_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">model_to_follow</span><span class="plain-syntax">, </span><span class="identifier-syntax">MD</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">roster_state</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">roster_state</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">counter</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-mrp.html#SP7">&#167;7</a> (three times).</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="7-im.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresschapter"><a href="2-gnr.html">2</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresschapter"><a href="6-st.html">6</a></li><li class="progresscurrentchapter">7</li><li class="progresssection"><a href="7-tm.html">tm</a></li><li class="progresssection"><a href="7-eip.html">eip</a></li><li class="progresssection"><a href="7-ti.html">ti</a></li><li class="progresssection"><a href="7-tc.html">tc</a></li><li class="progresssection"><a href="7-dc.html">dc</a></li><li class="progresssection"><a href="7-dr.html">dr</a></li><li class="progresssection"><a href="7-im.html">im</a></li><li class="progresscurrent">mrp</li><li class="progresssection"><a href="7-id.html">id</a></li><li class="progresssection"><a href="7-it.html">it</a></li><li class="progresssection"><a href="7-il.html">il</a></li><li class="progresssection"><a href="7-imn.html">imn</a></li><li class="progresssection"><a href="7-gi.html">gi</a></li><li class="progresssection"><a href="7-ei.html">ei</a></li><li class="progressnext"><a href="7-id.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

